package com.jnzc.ocr.serv.shop.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jnzc.ocr.common.bean.Tree;
import com.jnzc.ocr.common.utils.ArrayHandleUtils;
import com.jnzc.ocr.common.utils.DateUtils;
import com.jnzc.ocr.common.utils.TreeUtils;
import com.jnzc.ocr.common.utils.ValidateUtils;
import com.jnzc.ocr.dependencies.serv.mybatis.MybatisServiceImpl;
import com.jnzc.ocr.serv.shop.entity.ShopProduct;
import com.jnzc.ocr.serv.shop.entity.ShopProductAttr;
import com.jnzc.ocr.serv.shop.entity.ShopProductSku;
import com.jnzc.ocr.serv.shop.entity.ShopProductSkuAttr;
import com.jnzc.ocr.serv.shop.filter.ShopProductSkuFilter;
import com.jnzc.ocr.serv.shop.helper.ShopProductSkuHelper;
import com.jnzc.ocr.serv.shop.mapper.ShopProductSkuMapper;
import com.jnzc.ocr.serv.shop.service.ShopProductAttrService;
import com.jnzc.ocr.serv.shop.service.ShopProductService;
import com.jnzc.ocr.serv.shop.service.ShopProductSkuAttrService;
import com.jnzc.ocr.serv.shop.service.ShopProductSkuService;
import com.jnzc.ocr.serv.shop.vo.ShopProductSaveVo;
import com.jnzc.ocr.serv.shop.vo.ShopProductSkuSaveVo;
import com.jnzc.ocr.serv.shop.vo.ShopProductSkuVo;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @author zhangcm
 * @version 1.0, 2017-09-29
 */
@Service
public class ShopProductSkuServiceImpl extends MybatisServiceImpl<ShopProductSkuMapper, ShopProductSku, ShopProductSkuFilter> implements ShopProductSkuService {

    @Autowired
    private ShopProductAttrService shopProductAttrService;

    @Autowired
    private ShopProductService shopProductService;

    @Autowired
    private ShopProductSkuAttrService shopProductSkuAttrService;

    @Override
    protected void fillEntityWrapper(EntityWrapper<ShopProductSku> ew, ShopProductSkuFilter filter) {
        ShopProductSku entity = new ShopProductSku();
        entity.setId(filter.getId());
        entity.setShopId(filter.getShopId());
        entity.setProductId(filter.getProductId());
        ew.setEntity(entity);
        if(CollectionUtils.isNotEmpty(filter.getIdList())){
            ew.in("id", filter.getIdList());
        }
    }

    @Override
    public ShopProductSku find(Long id, Long shopId) {
        return this.find(id, null, shopId);
    }

    @Override
    public ShopProductSku find(Long id, Long productId, Long shopId) {
        ValidateUtils.isId(id, "SKU的ID");
        ShopProductSkuFilter filter = new ShopProductSkuFilter();
        filter.setId(id);
        filter.setProductId(productId);
        filter.setShopId(shopId);
        return super.findNotNull(filter);
    }

    @Override
    public List<ShopProductSku> list(List<Long> idList, Long shopId) {
        if(CollectionUtils.isEmpty(idList)) {
            return Lists.newArrayList();
        }
        ShopProductSkuFilter filter = new ShopProductSkuFilter();
        filter.setIdList(idList);
        filter.setShopId(shopId);
        return super.list(filter);
    }

    @Override
    public Map<Long, ShopProductSku> listMap(List<Long> idList, Long shopId) {
        List<ShopProductSku> list = this.list(idList, shopId);
        return ArrayHandleUtils.parseMap(list, "id");
    }

    @Override
    public List<ShopProductSku> list(Long productId, Long shopId) {
        ValidateUtils.isId(productId);
        ShopProductSkuFilter filter = new ShopProductSkuFilter();
        filter.setProductId(productId);
        filter.setShopId(shopId);
        return super.list(filter);
    }

    @Override
    public List<ShopProductSku> listWithAttr(Long productId, Long shopId, List<Tree<ShopProductAttr>> attrTree) {
        Map<Long, List<ShopProductSkuAttr>> skuAttrMap = shopProductSkuAttrService.listSkuMapByProductId(productId, shopId);
        List<ShopProductSku> list = this.list(productId, shopId);
        for (ShopProductSku obj : list) {
            List<ShopProductSkuAttr> skuAttrList = skuAttrMap.get(obj.getId());
            List<ShopProductAttr> attrList = Lists.newArrayList();
            if(CollectionUtils.isNotEmpty(skuAttrList)) {
                for (ShopProductSkuAttr skuAttr : skuAttrList) {
                    ShopProductAttr attr = TreeUtils.find(attrTree, skuAttr.getAttrId());
                    attrList.add(attr);
                }
            }
            obj.setAttrList(attrList);
        }
        return list;
    }

    @Override
    public List<Long> listIdByProductId(Long productId, Long shopId) {
        List<ShopProductSku> list = this.list(productId, shopId);
        return ArrayHandleUtils.readAttrList(list, "id");
    }

    @Override
    public List<ShopProductSkuVo> listVo(List<Long> idList, Long shopId) {
        List<ShopProductSkuVo> result = Lists.newArrayList();
        if(CollectionUtils.isEmpty(idList)) {
            return result;
        }
        List<ShopProductSku> list = this.list(idList, shopId);
        List<Long> productIdList = ArrayHandleUtils.readAttrList(list, "productId");
        Map<Long, ShopProduct> productMap = shopProductService.listMap(productIdList, shopId);
        for (ShopProductSku sku : list) {
            ShopProduct product = productMap.get(sku.getProductId());
            ShopProductSkuVo vo = new ShopProductSkuVo();
            vo.setProduct(product);
            vo.setSku(sku);
            result.add(vo);
        }
        return result;
    }

    @Override
    public Map<Long, ShopProductSkuVo> listVoMap(List<Long> idList, Long shopId) {
        Map<Long, ShopProductSkuVo> result = Maps.newHashMap();
        List<ShopProductSkuVo> list = this.listVo(idList, shopId);
        for (ShopProductSkuVo vo : list) {
            result.put(vo.getSku().getId(), vo);
        }
        return result;
    }

    @Override
    public void save(List<ShopProductSaveVo.Sku> paramList, ShopProduct product) {
        List<Tree<ShopProductAttr>> attrList = shopProductAttrService.listTree(product.getId(), product.getCategoryId(), product.getShopId());
        List<Long> oldIdList = this.listIdByProductId(product.getId(), product.getShopId());
        for (ShopProductSaveVo.Sku param : paramList) {
            ValidateUtils.notNull(param.getPrice(), "SKU价格");
            List<Long> attrParamIdList = ArrayHandleUtils.readAttrList(param.getAttrList(), "id");
            ShopProductSku obj = save(param, product, attrList, attrParamIdList);
            shopProductSkuAttrService.save(obj, attrParamIdList);
            param.setId(obj.getId());
            oldIdList.remove(obj.getId());
        }
        this.delete(oldIdList, product.getShopId());
    }

    private ShopProductSku save(ShopProductSaveVo.Sku param, ShopProduct product, List<Tree<ShopProductAttr>> attrList, List<Long> attrParamIdList) {
        ShopProductSku obj;
        if(null != param.getId()) {
            obj = this.find(param.getId(), product.getId(), product.getShopId());
        } else {
            obj = new ShopProductSku();
            obj.setShopId(product.getShopId());
            obj.setProductId(product.getId());
            obj.setCreateTime(DateUtils.getNow());
        }
        obj.setName(ShopProductSkuHelper.getName(attrList, attrParamIdList));
        obj.setAttr(ShopProductSkuHelper.getAttr(attrParamIdList));
        obj.setPrice(param.getPrice());
        super.save(obj);
        return obj;
    }

    @Override
    public void delete(Long productId, Long shopId) {
        ValidateUtils.isId(productId);
        shopProductSkuAttrService.deleteByProductId(productId, shopId);
        ShopProductSkuFilter filter = new ShopProductSkuFilter();
        filter.setProductId(productId);
        filter.setShopId(shopId);
        super.delete(filter);
    }

    @Override
    public void delete(List<Long> idList, Long shopId) {
        if(CollectionUtils.isEmpty(idList)){
            return;
        }
        shopProductSkuAttrService.deleteBySkuId(idList, shopId);
        ShopProductSkuFilter filter = new ShopProductSkuFilter();
        filter.setShopId(shopId);
        filter.setIdList(idList);
        super.delete(filter);
    }
}
